/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package nl.biggrid.plier.tools;

import nl.biggrid.plier.opm.Agent;
//import nl.uva.pcc.dnprov.opm.Agents;
import nl.biggrid.plier.event.Event;
//import nl.uva.pcc.dnprov.event.Events;
import nl.biggrid.plier.opm.Account;
//import nl.uva.pcc.dnprov.opm.Accounts;
import nl.biggrid.plier.opm.Artifact;
//import nl.uva.pcc.dnprov.opm.Artifacts;
//import nl.uva.pcc.dnprov.opm.CausalDependencies;
import nl.biggrid.plier.opm.Dependency;
import nl.biggrid.plier.opm.OPMGraph;
import nl.biggrid.plier.opm.Process;
//import nl.uva.pcc.dnprov.opm.Processes;
import nl.biggrid.plier.opm.Role;
import nl.biggrid.plier.opm.WasGeneratedBy;
import nl.biggrid.plier.opm.WasControlledBy;
import nl.biggrid.plier.opm.Used;
// added for OPM_AMC
import java.net.*;
import java.io.*;
import java.util.*;
import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;

/**
 *
 * @author vguevara
 */
public class OPM_AMC_instance {

    //static String[] query = new String[1000];
    private String wid = "";
    private String url = "";
    private LinkedHashSet<Agent> agentList;
    private LinkedHashSet<Process> processList;
    private LinkedHashSet<Event> eventList;
    private LinkedHashSet<Artifact> artifactList;
    private Hashtable inputArtifacts;
    private LinkedHashSet<Account> accountList;
    private LinkedHashSet<Dependency> causal;
    private Account account_abstract;
    private Account account_runable;
    private OPMGraph opmGraph;
    private Agent agent;
    private Role inputRole;
    private Role outputRole;
    private Role descRole;

    public OPM_AMC_instance(String parameter, String myurl) {
        this.wid = parameter;
        this.url = myurl;

        agentList = new LinkedHashSet<Agent>();
        inputArtifacts = new Hashtable();
        processList = new LinkedHashSet<Process>();
        eventList = new LinkedHashSet<Event>();
        artifactList = new LinkedHashSet<Artifact>();
        inputArtifacts = new Hashtable();
        accountList = new LinkedHashSet<Account>();
        causal = new LinkedHashSet<Dependency>();
        account_abstract = new Account();
        account_runable = new Account();
        opmGraph = new OPMGraph();
        agent = new Agent();
        inputRole = new Role();
        outputRole = new Role();
        descRole = new Role();
    }

    public OPMGraph getOPMGraph() {
        doProcess();
        return opmGraph;
    }

    private void doProcess() {
        try {
            inputRole.setValue("Input");
            outputRole.setValue("Output");
            descRole.setValue("Config");

//            String url = "https://hangplek.nikhef.nl/workflows//";
//            System.out.print("connecting to: " + url + "... ");

            System.out.println("\nProceeding with workflow: " + wid);

            Date d = new Date();

            opmGraph.setId(wid); // + ":" + d.toString());
            opmGraph.setDescription("OPM Graph for Experiement: " + wid + " Automatically Generated by by Plier_Crawler on: " + d.toString());
            agent = getAgent(url + wid + "/user.txt");
            createAbstract();
            createConcrete();
            agentList.add(agent);
            opmGraph.setAgents(agentList);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void createAbstract() throws Exception {

        account_abstract.setId(wid + "_Abstract");
        account_abstract.setValue(wid + "_Abstract");
        accountList.add(account_abstract);


//        agent.addAccount(account_abstract);
//        agentList.add(agent);

        System.out.println("A- Generating Abstract Workflow Model for Experiment: " + wid + " ...");

        // ---- Create OPM_PROCESS  *** from workflow jobs.txt *** ----
        ParseWorkflow(url + wid + "/workflow.xml");
//        ParseWorkflow2("https://hangplek.nikhef.nl/workflows//" + wid + "/workflow.xml");

        opmGraph.setAccounts(accountList);
//        opmGraph.setAgents(agentList);
        opmGraph.setArtifacts(artifactList);
        opmGraph.setProcesses(processList);
        opmGraph.setDependencies(causal);

    }

    private void createConcrete() throws Exception {

        account_runable.setId(wid + "_Concrete");
        account_runable.setValue(wid + "_Concrete");
        accountList.add(account_runable);
        agent.addAccount(account_runable);

        System.out.println("\nB- Generating Concrete Workflow Model for Experiment: " + wid + " ...");

        System.out.println("  a- Generating Processes:");
        // ---- Create OPM_PROCESS  *** from workflow jobs.txt *** ----
        createOPMInstances(url + wid + "/jobs.txt");

        System.out.println("  b- Generating Input Artifacts:");
        // ---- Create OPM_Artifacts  *** from file inputs.xml *** ----
        ParseInputArtifacts2(url + wid + "/input-m2.xml");

        System.out.println("  c- Parsing Input data files and creating the links to processes:");
        // ---- Create PLIER_EVENT  *** from workflow workflow.out *** ----
        ParseOutput(url + wid + "/workflow.out");

        System.out.println("  d- Parsing Output data files and creating the links to processes:");
        // ---- Create PLIER_EVENT  *** from workflow workflow.out *** ----
        ParseResults(url + wid + "/html/workflow-results.html");


        //eventList = this.getParseEvents(wid);

        // ---- Link each process to related events
        for (Process proc : processList) {
            for (Event event : eventList) {
                if (proc.getId().equals(validateId(event.getSource()))) {
                    proc.addEvent(event); //please come back and fix me!!!!!
//                    System.out.println(proc.getId() + " = " +(event.getSource()));
                }

            }
        }
        // ---- Link each process to the related agents   --- maybe not needed!!! ----
        /*
        Role r1 = new Role();
        r1.setValue("User");
        for (Process proc : processList) {

        WasControlledBy wcb = new WasControlledBy();
        wcb.setCause(agent);
        wcb.setEffect(proc);
        wcb.setRole(r1);
        //wcb.addAccount(account_runable);
        Dependency itemUser = new Dependency();
        itemUser.setWasControlledBy(wcb);
        causal.add(itemUser);
        }
         */




        opmGraph.setAccounts(accountList);
        opmGraph.setArtifacts(artifactList);
        opmGraph.setProcesses(processList);
        opmGraph.setEvents(eventList); //!!!!!!
        opmGraph.setDependencies(causal);

    }

    private int createOPMInstances(String myurl) throws Exception {
        int count = 1;

        Role r1 = new Role();
        r1.setValue("Host");



        URL myURL = new URL(myurl);
        URLConnection uc = myURL.openConnection();
        if (uc == null) {
            throw new Exception("Got a null URLConnection object!");
        //return 0;
        }

        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(myURL.openStream()));
            String myline;

            String processId = "";
            String processValue = "";
            while ((myline = in.readLine()) != null) {


                Process process = new Process();
                processId =
                        myline.substring(myline.lastIndexOf("/") + 1, myline.indexOf(" "));
                processValue =
                        myline.substring(myline.indexOf(" ") + 1, myline.length());
                String hostname = myline.substring(0, myline.lastIndexOf("/"));
                String hostId = validateId(hostname);


                System.out.println("\t" + (count++) + "- " + validateId(processId) + " (" + processId + ")");
                process.setId(validateId(processId));
                process.setValue(processValue);
                //process.addAccount(account_abstract);
                process.addAccount(account_runable);

                WasControlledBy wcb = new WasControlledBy();
                Agent agent = null;
                for (Agent chk : agentList) {
                    if (chk.getValue().equals(hostname)) {
                        agent = chk;
                        //Role r1 = new Role();
                        //r1.setValue(hostname);
//                    wcb.setRole(r1);
                        break;  // break for

                    }
                }



                // If it is a new Agent we have to instantiate it
                if (agent == null) {
                    agent = new Agent();
                    agent.setId(hostId);
                    agent.setValue(hostname);
                    agent.addAccount(account_runable);
                    agentList.add(agent);
                }

                wcb.setRole("Host");
                wcb.setCause(agent.getId());
                wcb.setEffect(process.getId());

                //Role r1 = new Role();
//            r1.setValue(agent.getId());
//            wcb.setRole(r1);

//            System.out.println("\n\nProcess: " + process.getId() + "-" + process.getValue() + ", controlled by:" + agent.getId() + "-" + agent.getValue() + ", Role:" + r1.getValue());


                //wcb.addAccount(accGreen.getId());

//            accountList.add(account_local);
                //Dependency itemUser = new Dependency();
                //itemUser.setWasControlledBy(wcb);

                causal.add(wcb);
                processList.add(process);

                count++;

            }




            in.close();

        } catch (IOException e) {
            System.out.println("\nERROR : '" + e.toString() + "'");
            e.printStackTrace();
        }

        return count;


    }

    private Agent getAgent(
            String myurl) throws Exception {
        URL myURL = new URL(myurl);
        BufferedReader in = new BufferedReader(new InputStreamReader(myURL.openStream()));
        String inputLine = "";
        int l=0;


        Agent agent1 = new Agent();
        if ((inputLine = in.readLine()) != null) {
            if (inputLine.indexOf("/CN=proxy") > 0)
                l = inputLine.indexOf("/CN=proxy");
            else
                l = inputLine.length();
            System.out.println("\tl: " + l);
            inputLine = inputLine.substring(inputLine.indexOf("/CN=") + 4, l);
        }

        in.close();

        agent1.setValue(inputLine);
        agent1.setId(validateId(inputLine));

        return agent1;
    }

    private int ParseOutput(String myurl) throws Exception {
        /*--- Problem of microseconds needs to be solved ---*/
        int start = 0;
        //int[] index = new int[3];
        String[] files = new String[5000];
        URL myURL = new URL(myurl);
        BufferedReader in = new BufferedReader(new InputStreamReader(myURL.openStream()));
        String myline;

        String tempArtifacts = "";
        while ((myline = in.readLine()) != null) {
            if (myline.indexOf(" GASW job with the following parameters") > 0) {
                int l = 0;
                while ((myline = in.readLine()) != null && myline.indexOf("[RUN] Job successfully submitted, job_id is ") < 0) {
                    if ((myline.indexOf(" [RUN] ") < 1) && (myline.indexOf("> [wf ") < 1) && (myline.indexOf("> Thread") < 1)) {
                        files[l] = myline.substring(myline.indexOf("> ") + 2, myline.length());
                        System.out.println("\tFile: " + files[l]);
                        l++;

                    }
                    //System.out.println("\tmyline: " + myline);

                    if (myline.indexOf(" Status of job ") > 0) {
                        createEvent(myline, ++start);
                    }

                }
                String processName = myline.substring(myline.lastIndexOf("/") + 1, myline.length());
                String hostName = myline.substring(myline.indexOf(", job_id is ") + 12, myline.lastIndexOf("/"));
                //System.out.println("\tmyline2: " + myline);
                tempArtifacts =
                        linkArtifacts2Process(files, validateId(processName), l, tempArtifacts);
//                break;
//                linkArtifacts2Process(files, processName.substring(0,processName.indexOf("-")), hostName,l);
            // Link process to input
            //myline = in.readLine();
            }
//System.out.println("\tmyline3: " + myline);

            if (myline.indexOf(" Status of job ") > 0) {
                createEvent(myline, ++start);
            }

        }
        in.close();

        return start;
    }

    private int ParseResults(String myurl) throws Exception {
        /*--- Problem of microseconds needs to be solved ---*/
        int start = 0;
        String artifacts[] = new String[1000];
        int i= 0;
        URL myURL = new URL(myurl);
        BufferedReader in = new BufferedReader(new InputStreamReader(myURL.openStream()));
        String outputId = "";
        String outputValue = "";
        String myline;

        while ((myline = in.readLine()) != null) {
            if (myline.indexOf("<h2>") >= 0) {
                outputId = myline.substring(myline.indexOf("<h2>") + 4, myline.indexOf("</h2>"));
                myline =
                        myline.substring(myline.indexOf("</h2>") + 5, myline.length());
                System.out.println("\t" + outputId);
                        //System.out.println("myline 1 is: " + myline);

                int s = 1;
                int t = 1;

                while (myline.indexOf("<a href=") >= 0) {
                    String myline2 = myline.substring(myline.indexOf("<a href=") + 9, myline.indexOf("\">"));
                        myline2 = myline2.replace("[", "");
                        myline2 = myline2.replace("][", "");
                        myline2 = myline2.replace("]", "");
                        myline2 = myline2.replace(", ", ",");
                        myline2 = myline2.replace(",,", ",");
                        myline2 = myline2.replace("null,", "");
                    if (myline2.indexOf(",") >= 0) {
                        //System.out.println("myline 2 is: " + myline2);
                        s = 1;
                        while (myline2.indexOf(",") >= 0 && !outputValue.equals(myline2.substring(0, myline2.indexOf(",")))) {
                            outputValue = myline2.substring(0, myline2.indexOf(","));
                            artifactList.add(addArtifact(outputId + "_" + (t) + (s), outputValue));
                            System.out.println("\t  " + outputId + "_" + (t) + (s) + ": " + outputValue);
                            artifacts[i++] = outputId;
                            myline2 = myline2.substring(myline2.indexOf(",") + 1, myline2.length());
                            //System.out.println("myline 2a is: " + myline2);
                            s++;
                        }

//                        System.out.println("myline 3 is: " + myline2);
//
//
//
//                        outputValue = myline2.substring(0, myline2.length() - 1);
//                        artifactList.add(addArtifact(outputId + "_" + (t) + (s), outputValue));
//                        System.out.println("\t  " + outputId + "_" + (t) + (s) + ": " + outputValue);
                    } else {
                        artifactList.add(addArtifact(outputId + "_" + (t), myline2));
                        System.out.println("\t  " + outputId + "_" + (t) + ": " + myline2); // size log file
                        artifacts[i++] = outputId;
                    }

                    myline = myline.substring(myline.indexOf("</a>") + 4, myline.length());
                    t++;
//System.out.println("myline4 is: " + myline);
//break;

                }
//                String processName=myline.substring(myline.lastIndexOf("/")+1, myline.length());
//                String hostName=myline.substring(myline.indexOf(", job_id is ")+12,myline.lastIndexOf("/"));
//                System.out.println("Job: " + processName);
//                linkArtifacts2Process(files, validateId(processName), hostName,l);

            }

        }
        in.close();
        linkOutputToProcess(artifacts);

        return start;
    }

    private String linkArtifacts2Process(
            String[] files, String process, int l, String tempArtifacts) {

        Process proc = null;
        Artifact art = new Artifact();
        Role role = null;
        String r1 = "Input";
        boolean found=false;

        for (Process p : processList) {
            if (p.getId().indexOf(process) == 0) {
                proc = p; break;
            }
        }

        for (int s = 0; s <l; s++) {
//      System.out.println("trying: " + proc.getId() + "(" + process + ") To " + files[s] + " host:" + host + " l="+l);
//      System.out.println("trying: " + process + " To " + files[s] + " host:" + host + " l="+l);
//      System.out.println("trying: " + process + " To " + files[s] + " host:" + host);
            found=false;
            for (Artifact chk : artifactList) {
                if (chk.getValue().equals(files[s])) {
                    art = chk;
                    found=true;
                    //System.out.println("tempArtifact is: " + tempArtifacts + "(" + files[s]);
//                if (tempArtifacts.indexOf(files[s]+"_")>0) {
                    if (tempArtifacts.equals(files[s] + "_")) {
                        role = descRole;
                        r1 = "Description";
                    //System.out.println("\trole is: " + role.getValue());
                    } else {
                        role = inputRole;
                        r1 = "Input";
                    }
                    // Linking Artifact to Process
                    if (proc!=null) {
                            Used used = new Used();
                            Role r = new Role();
                            r.setValue(art.getId());
                            if (art.getId().lastIndexOf("_")>0)
                                r.setValue(art.getId().substring(0,art.getId().lastIndexOf("_")));
                            used.setCause(art.getId());
                            used.setEffect(proc.getId());
                            used.setRole(r.getValue());
                            System.out.println("\tLink2 from: " + proc.getId() + " To " + art.getId() + "(" + art.getValue() + ")\trole: " + r.getValue());

                            causal.add(used);
                    }
                }
            }
            if (!found) {
//            Artifact art2 = new Artifact();
                String artid = files[s].substring(files[s].lastIndexOf("/") + 1, files[s].length());
//            System.out.println("new artifact is: " + files[s] + "\tid:" + artid);
                art.setId(validateId(artid));
                art.setValue(files[s]);
                art.addAccount(account_runable);
                artifactList.add(art);
//            role.setValue("Description");
                tempArtifacts = tempArtifacts + files[s] + "_";
                if (proc!=null) {
                    Used used = new Used();
                    Role r = new Role();
                    r.setValue("Config");
                    used.setCause(art.getId());
                    used.setEffect(proc.getId());
                    used.setRole("Config");
                    causal.add(used);
                }
                System.out.println("\tNew artifact: " + art.getId() + ": " + art.getValue());
            }
        }
        return tempArtifacts;
    }

    private int linkOutputToProcess(String[] artifacts) {

        //Process process = null;
        //Artifact artifact = new Artifact();
        Role role = new Role();
        role.setValue("Output");
        String temp="";
        int idx1= 0;
        int idx2=0;
        for (Process proc : processList) {
            idx1 =idx2 = 0;
            if (proc.getValue().indexOf("-") >0 )
                idx1 = proc.getValue().indexOf("-");
            if (idx1 >0 && proc.getValue().indexOf("-", idx1+1) >0 )
                idx2 = proc.getValue().indexOf("-", idx1+1);
            if (idx2 >0 && proc.getValue().indexOf("-", idx2) >0 ) {
                temp = proc.getValue().substring(idx2+1, proc.getValue().indexOf("-", idx2+1));
                //process = proc;
                //System.out.println("\t---- Process ----: " + proc.getValue() + "-->" + temp);
//                for (int l=0; l<=artifacts.length; l++) {
                for (Artifact art : artifactList) {
                    if (art.getValue().indexOf(temp)>=0) {
                        //artifact = art;
                        System.out.println("\tLinking process: " + proc.getValue() + " To output " + art.getValue() + "\trole: " + role.getValue());
                        WasGeneratedBy wgb = new WasGeneratedBy();
                        wgb.setEffect(art.getId());
                        wgb.setCause(proc.getId());
                        wgb.setRole(role.getValue());
                        causal.add(wgb);
                    }
                }
            }
        }
        return 0;
    }

    private void ParseInputArtifacts2(String myurl) {
        try {

            URL myURL = new URL(myurl);
            //   Artifact artifact = new Artifact();
            String artifactID = "";
            String artifactValue = "";

            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputStream stream = myURL.openStream();
            Document doc = db.parse(stream);
            doc.getDocumentElement().normalize();
            //System.out.println("Root element " + doc.getDocumentElement().getNodeName());

            int count = 1;

            //get the root elememt
            Element docEle = doc.getDocumentElement();
            //get a nodelist of <process> elements
            //Role r1 = new Role();
            //r1.setValue("Input");
            NodeList nl_source = docEle.getElementsByTagName("source");
            if (nl_source != null && nl_source.getLength() > 0) {
                for (int i = 0; i <
                        nl_source.getLength(); i++) {
                    Element el_src = (Element) nl_source.item(i);
                    artifactID =
                            el_src.getAttribute("name");  // assign artifact ID
                    //System.out.println("source element: " + el_src.getAttribute("name"));
                    Node srcNode = nl_source.item(i);
                    if (srcNode.getNodeType() == Node.ELEMENT_NODE) {
                        Element fstElmnt = (Element) srcNode;
                        NodeList nl_array = fstElmnt.getElementsByTagName("array");
                        for (int j = 0; j <
                                nl_array.getLength(); j++) {
                            Element el_array = (Element) nl_array.item(j);  //element of node array

                            NodeList nl_item = el_array.getElementsByTagName("item");
                            for (int k = 0; k <
                                    nl_item.getLength(); k++) {
                                Artifact artifact = new Artifact();
                                Element fstNmElmnt = (Element) nl_item.item(k);  //element of node item
                                NodeList fstNm = fstNmElmnt.getChildNodes();
                                //artifactID=artifactID + ((Element) fstNm.item(0)).getAttribute("value").toString();  // assign artifact ID
                                if (!artifactValue.equals((fstNm.item(1)).getNodeValue())){
                                    artifact.setId(validateId(artifactID + "_" + ((Element) fstNm.item(0)).getAttribute("value")));
                                    artifact.setValue((fstNm.item(1)).getNodeValue());
                                    artifact.addAccount(account_runable);
                                    artifactList.add(artifact);
                                    artifactValue = (fstNm.item(1)).getNodeValue();
                                    System.out.println("\t" + (count++) + "- " + artifactID + "_" + ((Element) fstNm.item(0)).getAttribute("value") + ": " + (fstNm.item(1)).getNodeValue());
                                }

                            }

                        }
                    }
                }
            }


        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void ParseWorkflow(String myurl) {
        try {

            // Create Input and Output Role
            Role inputRole = new Role();
            inputRole.setValue("Input");
            Role outputRole = new Role();
            outputRole.setValue("Output");


            URL myURL = new URL(myurl);
            //   Artifact artifact = new Artifact();
            //String
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputStream stream = myURL.openStream();
            Document doc = db.parse(stream);
            doc.getDocumentElement().normalize();

            String from = "";
            String to = "";
            String processor1 = "";
            String input1 = "";

            //get the root elememt
            Element docEle = doc.getDocumentElement();
            if (docEle.getNodeName().equals("s:scufl")) {
                System.out.println("\tworkflow description is using the old scufl format ...");
                //System.out.println("\t    --> Abstract OPM/workflow model will not be created");
                //System.out.println("\t    --> Concrete OPM/workflow model will not be complete/accurate");

                NodeList nl = docEle.getElementsByTagName("s:scufl");
                System.out.println("\tscufl: " + nl.getLength() + " links");
                NodeList items = docEle.getElementsByTagName("s:link");
                System.out.println("\tlink: " + items.getLength() + " links");
                for (int j = 0; j <
                        items.getLength(); j++) {
                    Element fstNmElmnt = (Element) items.item(j);
                    from =
                            fstNmElmnt.getAttribute("source");
                    to =
                            fstNmElmnt.getAttribute("sink");
                    System.out.println("Link from: " + from + " To: " + to);
                    if (from.indexOf(":") > 0 && to.indexOf(":") > 0) {
                        processor1 = from.substring(0, from.indexOf(":"));
                        input1 =
                                from.substring(from.indexOf(":") + 1, from.length());
                        System.out.println("\tProcess: " + ": " + processor1 + " output: " + input1);
                        linkArtifact2(processor1, to.substring(to.indexOf(":") + 1, to.length()), outputRole);
                        System.out.println("\tProcess: " + ": " + to.substring(0, to.indexOf(":")) + " input: " + input1);
                        System.out.println("\tVia link: " + to.substring(to.indexOf(":") + 1, to.length()));
                        linkArtifact2(to.substring(0, to.indexOf(":")), to.substring(to.indexOf(":") + 1, to.length()), inputRole);
                    }

                    if (from.indexOf(":") < 0 && to.indexOf(":") > 0) {
                        System.out.println("\tProcess: " + ": " + to.substring(0, to.indexOf(":")) + " input: " + from);
                        System.out.println("\tVia link: " + to.substring(to.indexOf(":") + 1, to.length()));
                        linkArtifact2(to.substring(0, to.indexOf(":")), from, inputRole);
                    }

                    if (from.indexOf(":") > 0 && to.indexOf(":") < 0) {
                        System.out.println("\tProcess: " + ": " + from.substring(0, from.indexOf(":")) + " output: " + to);
                        System.out.println("\tVia link: " + from.substring(from.indexOf(":") + 1, from.length()));
                        linkArtifact2(from.substring(0, from.indexOf(":")), to, outputRole);
                    }

                }

            } else {
                NodeList nl = docEle.getElementsByTagName("links");
                if (nl != null && nl.getLength() > 0) {
                    for (int i = 0; i <
                            nl.getLength(); i++) {
                        //Element el = (Element)nl.item(i);
                        Node fstNode = nl.item(i);
                        if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
                            Element fstElmnt = (Element) fstNode;
                            NodeList items = fstElmnt.getElementsByTagName("link");
                            for (int j = 0; j <
                                    items.getLength(); j++) {
//                        Process process = new Process();
                                Element fstNmElmnt = (Element) items.item(j);
                                from =
                                        fstNmElmnt.getAttribute("from");
                                to =
                                        fstNmElmnt.getAttribute("to");
                                System.out.println("Link from: " + from + " To: " + to);
                                if (from.indexOf(":") > 0 && to.indexOf(":") > 0) {
                                    processor1 = from.substring(0, from.indexOf(":"));
                                    input1 =
                                            from.substring(from.indexOf(":") + 1, from.length());
                                    System.out.println("\tProcess: " + ": " + processor1 + " output: " + input1);
                                    linkArtifact2(processor1, to.substring(to.indexOf(":") + 1, to.length()), outputRole);
                                    //linkArtifact2(processor1, input1, outputRole);
                                    System.out.println("\tProcess: " + ": " + to.substring(0, to.indexOf(":")) + " input: " + input1);
                                    System.out.println("\tVia link: " + to.substring(to.indexOf(":") + 1, to.length()));
                                    linkArtifact2(to.substring(0, to.indexOf(":")), to.substring(to.indexOf(":") + 1, to.length()), inputRole);
                                //linkArtifact2(to.substring(0, to.indexOf(":")), input1, inputRole);
                                }

                                if (from.indexOf(":") < 0 && to.indexOf(":") > 0) {
                                    System.out.println("\tProcess: " + ": " + to.substring(0, to.indexOf(":")) + " input: " + from);
                                    System.out.println("\tVia link: " + to.substring(to.indexOf(":") + 1, to.length()));
                                    linkArtifact2(to.substring(0, to.indexOf(":")), from, inputRole);
                                }

                                if (from.indexOf(":") > 0 && to.indexOf(":") < 0) {
                                    System.out.println("\tProcess: " + ": " + from.substring(0, from.indexOf(":")) + " output: " + to);
                                    System.out.println("\tVia link: " + from.substring(from.indexOf(":") + 1, from.length()));
                                    linkArtifact2(from.substring(0, from.indexOf(":")), to, outputRole);
                                }

                            }
                        }
                    }
                }
            }

        //while (inputArtifacts.elements())
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void ParseWorkflow2(String myurl) {
        try {

            // Create Input and Output Role
            Role inputRole = new Role();
            inputRole.setValue("Input");
            Role outputRole = new Role();
            outputRole.setValue("Output");


            URL myURL = new URL(myurl);
            //   Artifact artifact = new Artifact();
            //String
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputStream stream = myURL.openStream();
            Document doc = db.parse(stream);
            doc.getDocumentElement().normalize();


            //get the root elememt
            Element docEle = doc.getDocumentElement();
            if (docEle.getNodeName().equals("s:scufl")) {
                System.out.println("\tworkflow description is using the old scufl format ...");

            }

            String from = "";
            String to = "";
            String processor1 = "";
            String input1 = "";
            NodeList nl = docEle.getElementsByTagName("s:scufl");
            System.out.println("\tscufl: " + nl.getLength() + " links");
            NodeList items = docEle.getElementsByTagName("s:link");
            System.out.println("\tlink: " + items.getLength() + " links");
            for (int j = 0; j <
                    items.getLength(); j++) {
                Element fstNmElmnt = (Element) items.item(j);
                from =
                        fstNmElmnt.getAttribute("source");
                to =
                        fstNmElmnt.getAttribute("sink");
                System.out.println("Link from: " + from + " To: " + to);
                if (from.indexOf(":") > 0 && to.indexOf(":") > 0) {
                    processor1 = from.substring(0, from.indexOf(":"));
                    input1 =
                            from.substring(from.indexOf(":") + 1, from.length());
                    System.out.println("\tProcess: " + ": " + processor1 + " output: " + input1);
                    linkArtifact2(processor1, to.substring(to.indexOf(":") + 1, to.length()), outputRole);
                    System.out.println("\tProcess: " + ": " + to.substring(0, to.indexOf(":")) + " input: " + input1);
                    System.out.println("\tVia link: " + to.substring(to.indexOf(":") + 1, to.length()));
                    linkArtifact2(to.substring(0, to.indexOf(":")), to.substring(to.indexOf(":") + 1, to.length()), inputRole);
                }

                if (from.indexOf(":") < 0 && to.indexOf(":") > 0) {
                    System.out.println("\tProcess: " + ": " + to.substring(0, to.indexOf(":")) + " input: " + from);
                    System.out.println("\tVia link: " + to.substring(to.indexOf(":") + 1, to.length()));
                    linkArtifact2(to.substring(0, to.indexOf(":")), from, inputRole);
                }

                if (from.indexOf(":") > 0 && to.indexOf(":") < 0) {
                    System.out.println("\tProcess: " + ": " + from.substring(0, from.indexOf(":")) + " output: " + to);
                    System.out.println("\tVia link: " + from.substring(from.indexOf(":") + 1, from.length()));
                    linkArtifact2(from.substring(0, from.indexOf(":")), to, outputRole);
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void linkArtifact2(String processname, String artifactname, Role role) {
        try {

            Artifact artifact = null;
            for (Artifact art : artifactList) {
                if (art.getId().equals(artifactname)) {
                    artifact = art;
                    break;  // break for

                }
            }

            //If it is a new Artifact we have to instantiate it
            if (artifact == null) {
                artifact = new Artifact();
                artifact.setId(validateId(artifactname));
                artifact.setValue(artifactname);
                artifact.addAccount(account_abstract);
                artifactList.add(artifact);
                System.out.println("New Artifact: " + artifactname);
            }

            Process process = null;
            for (Process proc : processList) {
                if (proc.getId().equals(processname)) {
                    process = proc;
                    break;  // break for

                }




            }

            //If it is a new Artifact we have to instantiate it
            if (process == null) {
                process = new Process();
                process.setId(validateId(processname));
                process.setValue(processname);
                process.addAccount(account_abstract);
                processList.add(process);
                //role.setValue("Description");
                System.out.println("New Process: " + processname);
            }

            Dependency itemUsed = new Dependency();

            if (role.getValue().equals("Input") || role.getValue().equals("Description")) {
                Used used = new Used();
                used.setCause(artifact.getId());
                used.setEffect(process.getId());
                //used.addAccount(account_abstract);
                used.setRole(role.getValue());
                inputArtifacts.put(process.getId(), artifact.getId());
                causal.add(used);

            }

            if (role.getValue().equals("Output")) {
                WasGeneratedBy generatedBy = new WasGeneratedBy();
                generatedBy.setCause(process.getId());
                generatedBy.setEffect(artifact.getId());
                //generatedBy.addAccount(account_abstract);
                generatedBy.setRole(role.getValue());
                //itemUsed.setWasGeneratedBy(generatedBy);
                causal.add(generatedBy);


            }

//                            r1 = null;
//                            for (Role rl : roleList.getRoleVector()) {
//                                if (rl.getValue().equals(role)) {
//                                    r1 = rl;
//                                    break;  // break for
//                                }
//                            }
//                        }



        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private Artifact addArtifact(String artId, String artValue) {
        Artifact artifact = new Artifact();
        boolean found=false;
        for (Artifact art : artifactList) {
            if (art.getValue().equals(artValue)) {
                found = true;
                break;  // break for
            }
        }

        if (!found) {
            artifact.setId(validateId(artId));
            artifact.setValue(artValue);
            artifact.addAccount(account_runable);
            artifactList.add(artifact);
            System.out.println("\n\tArtifact " + artId + ": "+ artValue);
        }
        return artifact;
    }

    private boolean isIntNumber(String num) {
        try {
            Integer.parseInt(num);
        } catch (NumberFormatException nfe) {
            return false;
        }

        return true;
    }

    private String validateId(
            String stringId) {
        stringId = stringId.replace("://", "_");
        stringId =
                stringId.replace(":", "_");
        stringId =
                stringId.replace("/", "_");
        stringId =
                stringId.replace("-", "_");
        stringId =
                stringId.replace(".", "_");
        stringId =
                stringId.replace(" ", "_");
        stringId =
                stringId.replace("(", "_");
        stringId =
                stringId.replace(")", "_");
        stringId =
                stringId.replace("=", "_");
        if (isIntNumber(stringId.substring(0, 1))) {
            stringId = "_".concat(stringId);
        }

        return stringId;
    }

    private void createEvent(String myline, int start) {
        int[] index = new int[3];
        index[0] = myline.indexOf(" Status of job ") + 15;
        index[1] = myline.indexOf(" is ");
        index[2] = myline.length();
        Event event = new Event();
        event.setId(start);
        event.setIdentification("STATUS");
        event.setDescription(myline.substring(index[1] + 4, index[2]));
        //event.setSource(myline.substring(index[0], index[1]));
        event.setSource(validateId(myline.substring(myline.lastIndexOf("/") + 1, index[1])));
        event.setSourceName("Moteur/Diane");
        event.setHost(myline.substring(index[0], myline.lastIndexOf("/")));
        String strDate = myline.substring(0, myline.indexOf(" "));
        Date date = new Date(Long.parseLong(strDate));
        if (strDate.length() == 11) {
            date = new Date(Long.parseLong(strDate) * 100);
        }

        if (strDate.length() == 12) {
            date = new Date(Long.parseLong(strDate) * 10);
        }


//                Date date = new Date(Long.parseLong(myline.substring(0, myline.indexOf(" "))) * 10);
        System.out.println("\tEvent_" + start + ": Process " + event.getSource() + " " + event.getDescription() + " on " + event.getHost());
        //addArtifact("Host",event.getHost());
        event.setTimestamp(date);

        event.setLevel(2); //Information
        event.setCode(0); // ??? Code for developers
        event.setCategory(2); //WebService

        eventList.add(event);
    }
}
